Obsidian TC マンスリービュー
code:js
`dataviewjs
// 現在の年月を取得
let today = new Date();
let year = today.getFullYear();
let month = today.getMonth(); // JavaScriptの月は0が1月、11が12月
// カレンダーを生成する関数
async function generateCalendar(year, month, filterText = '') {
const specifiedMonth = window.moment(year, month); // 指定された月 const firstDayOfMonth = specifiedMonth.startOf('month');
const daysInMonth = specifiedMonth.daysInMonth();
const fs = app.vault.adapter; // ObsidianのファイルシステムにアクセスするためのAPI
// カレンダーテーブルのスタイルを設定
let calendarHTML = `
<style>
table.calendar {
width: 100%;
table-layout: fixed; /* 列幅を均一に */
}
table.calendar th, table.calendar td {
padding: 5px;
text-align: center;
vertical-align: top;
}
table.calendar td {
height: 100px; /* セルの高さを統一 */
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.text-list {
text-align: left;
font-size: 10px;
}
.calendar-day {
color: gray;
font-size: 12px;
margin-bottom: 8px;
display: block;
}
.calendar-weekday {
color: gray;
font-size: 12px;
}
</style>
<div class="calendar-header">
<h2>${year}年 ${specifiedMonth.format('M')}月</h2>
<div>
<input type="text" id="filterText" placeholder="フィルターする文字列を入力" value="${filterText}">
<button id="applyFilter">フィルター</button>
<button id="prevMonth">< 前の月</button>
<button id="nextMonth">次の月 ></button>
</div>
</div>
<table class="calendar" border="1">
`;
// 曜日のヘッダーを作成
calendarHTML += `<tr>
<th class="calendar-weekday">Sun</th>
<th class="calendar-weekday">Mon</th>
<th class="calendar-weekday">Tue</th>
<th class="calendar-weekday">Wed</th>
<th class="calendar-weekday">Thu</th>
<th class="calendar-weekday">Fri</th>
<th class="calendar-weekday">Sat</th>
</tr><tr>`;
// 月の最初の日の曜日を取得して、空白セルを追加
let firstDayWeekday = firstDayOfMonth.day();
for (let i = 0; i < firstDayWeekday; i++) {
calendarHTML += <td></td>;
}
// 日付ごとにループし、データを取得
for (let day = 1; day <= daysInMonth; day++) {
const dateString = specifiedMonth.clone().startOf('month').add(day - 1, 'days').format('YYYY-MM-DD');
const filePath = notes/${dateString}.md; // デイリーノートが保存されているパス
let textsForDay = new Set();
if (await fs.exists(filePath)) {
const fileContent = await dv.io.load(filePath);
const lines = fileContent.split('\n');
lines.forEach(line => {
if (line.includes(filterText)) {
textsForDay.add(line.trim());
}
});
if (textsForDay.size > 0) {
calendarHTML += <td><strong class="calendar-day">${day}</strong><div class="text-list">;
textsForDay.forEach(text => {
calendarHTML += <div>${text}</div>;
});
calendarHTML += </div></td>;
} else {
calendarHTML += <td><strong class="calendar-day">${day}</strong></td>;
}
} else {
calendarHTML += <td><strong class="calendar-day">${day}</strong></td>;
}
if ((day + firstDayWeekday) % 7 === 0) {
calendarHTML += </tr><tr>;
}
}
let lastDayWeekday = (firstDayWeekday + daysInMonth) % 7;
if (lastDayWeekday !== 0) {
for (let i = lastDayWeekday; i < 7; i++) {
calendarHTML += <td></td>;
}
}
calendarHTML += </tr></table>;
// カレンダーを表示
dv.container.innerHTML = calendarHTML;
}
// イベントリスナーを追加
document.addEventListener("click", function (event) {
if (event.target && event.target.id === "prevMonth") {
month--;
if (month < 0) {
month = 11;
year--;
}
generateCalendar(year, month, document.getElementById("filterText").value);
}
if (event.target && event.target.id === "nextMonth") {
month++;
if (month > 11) {
month = 0;
year++;
}
generateCalendar(year, month, document.getElementById("filterText").value);
}
if (event.target && event.target.id === "applyFilter") {
const filterText = document.getElementById("filterText").value;
generateCalendar(year, month, filterText);
}
});
// 初期表示のカレンダーを生成
generateCalendar(year, month);
`